package com.atguigu.tingshu.search.runnable;

import com.atguigu.tingshu.search.factory.ScheduleTaskThreadPoolFactory;
import com.atguigu.tingshu.search.service.ItemService;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class RebuildBloomFilterRunnable implements Runnable {

    Logger log = LoggerFactory.getLogger(this.getClass());

    private RedissonClient redissonClient;

    private StringRedisTemplate redisTemplate;

    private ItemService itemService;


    public RebuildBloomFilterRunnable(RedissonClient redissonClient, StringRedisTemplate redisTemplate, ItemService itemService) {
        this.redissonClient = redissonClient;
        this.redisTemplate = redisTemplate;
        this.itemService = itemService;
    }

    @Override
    public void run() {
        RBloomFilter<Object> albumIdBloomFilter = redissonClient.getBloomFilter("albumIdBloomFilterNew");
        albumIdBloomFilter.tryInit(1000000, 0.01);

        for (Long albumId : itemService.findAllAlbumId()) {
            albumIdBloomFilter.add(albumId);
        }
        String script = " redis.call(\"del\",KEYS[1])" +
                "  redis.call(\"del\",KEYS[2])" +
                "  redis.call(\"rename\",KEYS[3],KEYS[1])" +
                "  redis.call(\"rename\",KEYS[4],KEYS[2]) return 0";
        List<String> asList = Arrays.asList("albumIdBloomFilter", "{albumIdBloomFilter}:config", "albumIdBloomFilter:new", "{albumIdBloomFilter:new}:config");
        Long exec = redisTemplate.execute(new DefaultRedisScript<Long>(script, Long.class), asList);
        if (exec == 0)
            log.info("新布隆替换老布隆成功，已上线。");
        // todo 写一个线程工厂
        ScheduleTaskThreadPoolFactory.getInstance().execute(this, 7, TimeUnit.DAYS);
    }
}
